import networkx as nx
from collections import deque


def is_power_of_two(n):
    return n > 0 and (n & (n - 1)) == 0


def find_power_of_two_connected_subgraphs_optimized(G):
    nodes = list(G.nodes())
    V = len(nodes)
    result = set()  # 使用集合存储排序后的节点元组去重

    # 生成所有可能的2的幂次方大小（1, 2, 4, ..., 最大不超过V）
    max_k = V.bit_length()
    for s in [2 ** k for k in range(max_k) if 2 ** k <= V]:
        if s == 1:
            # 处理大小为1的子图（每个节点自身）
            for node in nodes:
                result.add((node,))
        else:
            # 对每个节点作为起点，进行BFS扩展到大小为s的连通子图
            for start_node in nodes:
                # 使用队列存储 (当前节点集合, 当前节点的邻居集合)
                queue = deque()
                queue.append(({start_node}, set(G.neighbors(start_node))))

                while queue:
                    current_nodes, neighbors = queue.popleft()
                    current_size = len(current_nodes)

                    if current_size == s:
                        # 记录排序后的节点元组（去重）
                        sorted_nodes = tuple(sorted(current_nodes))
                        result.add(sorted_nodes)
                        continue

                    # 扩展到下一层：仅当当前大小 + 1 <= s时，尝试添加邻居
                    if current_size < s:
                        for neighbor in list(neighbors):  # 避免修改迭代中的集合
                            new_nodes = current_nodes.copy()
                            new_nodes.add(neighbor)#添加邻居后，邻居集合新增邻居的邻居
                            new_neighbors = neighbors.copy()
                            new_neighbors.update(G.neighbors(neighbor))
                            new_neighbors.difference_update(new_nodes)  # 邻居的邻居需排除已访问节点
                            queue.append((new_nodes, new_neighbors))

    # 将集合转换为networkx子图
    subgraphs = []
    for node_tuple in result:
        subgraph = G.subgraph(node_tuple)
        subgraphs.append(subgraph)

    return subgraphs

if __name__ == '__main__':
    # 示例图
    G = nx.Graph()
    G.add_edges_from([(1, 2), (2, 3), (3, 1), (4, 5), (5, 6), (6, 4), (2, 4)])  # 新增边2-4使图连通

    # 查找所有大小为2的n次方的连通子图
    optimized_subgraphs = find_power_of_two_connected_subgraphs_optimized(G)

    # 输出结果
    for subgraph in optimized_subgraphs:
        print(f"Nodes: {list(subgraph.nodes())}, Size: {len(subgraph.nodes())}")